package BandB.Tool.GPhoneManager.AppManager.Grid;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import BandB.Tool.GPhoneManager.ConfigManager;
import BandB.Tool.GPhoneManager.R;
import BandB.Tool.GPhoneManager.AppManager.UninstallerList;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class UninstallerGrid extends Activity {

	private static final String TAG = UninstallerGrid.class.getSimpleName();
	private static final byte[] SYNC = new byte[0];

	private static final int MSG_LOADING_APPS_BEGIN = 0;
	protected static final int MSG_LOADING_PACKAGES_BEGIN = 1;
	protected static final int MSG_ADAPTER_DATA_CHANGED = 3;
	protected static final int MSG_BACKUP_ONE_FILE_SUCCESS = 4;

	private static final int FLAG_SYSTEM = 0;
	private static final int FLAG_NO_SYSTEM = 1;

	private static final int MODE_SORT_BY_NAME = 0;
	private static final int MODE_SORT_BY_DATE = 1;
	private static final int MODE_SORT_BY_SIZE = 2;

	private static final int REQUEST_UNINSTALL = 1024;

	private static final int MODE_SHOW_ACTIVITY = 0;
	private static final int MODE_SHOW_ALL = 1;

	private static final int NOTIFYCATION_ID = 19881227;
	// private ActivityManager mActivityManager;
	private int sortMode;
	private int currentShowMode = 0;
	private SettingDialog settingDialog;
	private GridView grid;
	private TextView txtLoading;
	private ProgressDialog mProgressDialog;
	private PackageManager mPackageManager;
	private NotificationManager mNotificationManager;
	// private LayoutInflater mInflater;
	private List<PackageInfo> mPackageInfoList;
	private List<ResolveInfo> mApplicationInfoList;
	private UninstallerGridAdapter mUninstallerAdapter;
	private UninstallerGridAppAdapter mUninstallerGridAppAdapter;
	private Queue<PackageInfo> mQueuePackages;
	private Queue<ResolveInfo> mQueueApps;
	private ConfigManager mConfigManager;
	private ApplicationInfo currentApplicationInfo;
	private int currrentApplicationIndex;

	private final OnItemClickListener gridItemClick = new OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int position,
				long arg3) {
			// TODO Auto-generated method stub
			ApplicationInfo info = null;
			if (currentShowMode == MODE_SHOW_ACTIVITY) {
				info = mUninstallerGridAppAdapter.getInfo(position)
						.getResolveInfo().activityInfo.applicationInfo;
			} else {
				info = mUninstallerAdapter.getInfo(position).getPackageInfo().applicationInfo;
			}
			currrentApplicationIndex = position;
			currentApplicationInfo = info;
			final ApplicationInfo mApplicationInfo = info;
			final int index = position;

			if ((mApplicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
				Builder builder = new Builder(UninstallerGrid.this);
				builder.setTitle(R.string.warning);
				builder.setMessage(R.string.system_app);
				builder.setNegativeButton(R.string.no,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
							}
						});
				builder.setPositiveButton(R.string.yes,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								startUninstall(mApplicationInfo.packageName,
										FLAG_SYSTEM, index);
							}
						});
				builder.show();
			} else {
				// startApplicationDetailsActivity(mApplicationInfo.packageName);
				startUninstall(mApplicationInfo.packageName, FLAG_NO_SYSTEM,
						index);

			}
		}
	};

	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			switch (msg.what) {
			case MSG_BACKUP_ONE_FILE_SUCCESS:
				if (null != mProgressDialog) {
					mProgressDialog.dismiss();
				}
				Toast.makeText(UninstallerGrid.this, "Succeed to backup.",
						Toast.LENGTH_SHORT).show();
				break;
			case MSG_LOADING_APPS_BEGIN:
				txtLoading.setVisibility(View.VISIBLE);
				mUninstallerGridAppAdapter = new UninstallerGridAppAdapter(
						UninstallerGrid.this);
				grid.setAdapter(mUninstallerGridAppAdapter);
				new Thread(new Runnable() {

					@Override
					public void run() {
						// TODO Auto-generated method stub
						startLoadingApps();
					}
				}).start();
				break;
			case MSG_LOADING_PACKAGES_BEGIN:
				txtLoading.setVisibility(View.VISIBLE);
				mUninstallerAdapter = new UninstallerGridAdapter(
						UninstallerGrid.this);
				grid.setAdapter(mUninstallerAdapter);
				new Thread(new Runnable() {
					public void run() {
						startLoadingPackages();
					}
				}).start();
				break;
			case MSG_ADAPTER_DATA_CHANGED:
				txtLoading.setVisibility(View.GONE);
				if (currentShowMode == MODE_SHOW_ALL) {
					synchronized (SYNC) {
						mUninstallerAdapter.addQueueData(mQueuePackages);
						mUninstallerAdapter.sortByName();
						mUninstallerAdapter.notifyDataSetChanged();
						SYNC.notify();
					}
				} else {
					synchronized (SYNC) {
						mUninstallerGridAppAdapter.addQueueData(mQueueApps);
						mUninstallerGridAppAdapter.sortByName();
						mUninstallerGridAppAdapter.notifyDataSetChanged();
						SYNC.notify();
					}
				}
				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
//		requestWindowFeature(Window.FEATURE_NO_TITLE);
		requestWindowFeature(Window.FEATURE_RIGHT_ICON);
		requestWindowFeature(Window.FEATURE_PROGRESS);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.uninstaller_grid);

		currentShowMode = getIntent().getIntExtra(UninstallerList.WHAT_MODE,
				MODE_SHOW_ACTIVITY);

		initializeElements();
		if (currentShowMode == MODE_SHOW_ACTIVITY) {
			mHandler.sendEmptyMessage(MSG_LOADING_APPS_BEGIN);
		} else {
			mHandler.sendEmptyMessage(MSG_LOADING_PACKAGES_BEGIN);
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.grid_menu, menu);
		Log.i(TAG, "create menu");
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuItem item = menu.getItem(1);
		if (currentShowMode == MODE_SHOW_ACTIVITY) {
			item.setTitle(R.string.menu_show_all);
		} else if (currentShowMode == MODE_SHOW_ALL) {
			item.setTitle(R.string.menu_show_app);
		}
		switch (sortMode) {
		case MODE_SORT_BY_NAME:
			menu.findItem(R.id.sort_by_name).setChecked(true);
			menu.findItem(R.id.sort_by_date).setChecked(false);
			menu.findItem(R.id.sort_by_size).setChecked(false);
			break;
		case MODE_SORT_BY_DATE:
			menu.findItem(R.id.sort_by_name).setChecked(false);
			menu.findItem(R.id.sort_by_date).setChecked(true);
			menu.findItem(R.id.sort_by_size).setChecked(false);
			break;
		case MODE_SORT_BY_SIZE:
			menu.findItem(R.id.sort_by_name).setChecked(false);
			menu.findItem(R.id.sort_by_date).setChecked(false);
			menu.findItem(R.id.sort_by_size).setChecked(true);
			break;
		default:
			break;
		}
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case R.id.sort_by_name:
			sortMode = MODE_SORT_BY_NAME;
			if (currentShowMode == MODE_SHOW_ALL) {
				mUninstallerAdapter.sortByName();
				mUninstallerAdapter.notifyDataSetChanged();
			} else {
				mUninstallerGridAppAdapter.sortByName();
				mUninstallerGridAppAdapter.notifyDataSetChanged();
			}

			break;
		case R.id.sort_by_size:
			sortMode = MODE_SORT_BY_SIZE;
			if (currentShowMode == MODE_SHOW_ALL) {
				mUninstallerAdapter.sortBySize();
				mUninstallerAdapter.notifyDataSetChanged();
			} else {
				mUninstallerGridAppAdapter.sortBySize();
				mUninstallerGridAppAdapter.notifyDataSetChanged();
			}
			break;
		case R.id.sort_by_date:
			sortMode = MODE_SORT_BY_DATE;
			if (currentShowMode == MODE_SHOW_ALL) {
				mUninstallerAdapter.sortByDate();
				mUninstallerAdapter.notifyDataSetChanged();
			} else {
				mUninstallerGridAppAdapter.sortByDate();
				mUninstallerGridAppAdapter.notifyDataSetChanged();
			}

			break;

		case R.id.menu_item_about:

			/**
			 * 这里About的功能还没有具体的实现
			 */

			break;

		case R.id.more_moreapps:

			/**
			 * 这里moreapps的功能还没有具体的实现
			 */
			Log.e("water", "enter moreapps");
			break;
		case R.id.more_feedback:
			/**
			 * 这里feedback的功能还没有具体的实现
			 */
			Log.e("water", "enter feedback");
			break;
		case R.id.moresetting:
			Log.e("water", "enter settings");
			settingDialog = new SettingDialog(this);
			settingDialog.show();
			break;

		case R.id.show_mode:
			if (currentShowMode == MODE_SHOW_ACTIVITY) {
				currentShowMode = MODE_SHOW_ALL;
				mHandler.sendEmptyMessage(MSG_LOADING_PACKAGES_BEGIN);
			} else {
				currentShowMode = MODE_SHOW_ACTIVITY;
				mHandler.sendEmptyMessage(MSG_LOADING_APPS_BEGIN);
			}
			break;

		default:
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == REQUEST_UNINSTALL || requestCode == 12) {
			Log.i(TAG, "activity returned, and requestCode is " + requestCode);
			try {
				if (currentApplicationInfo != null) {
					mPackageManager
							.getApplicationIcon(currentApplicationInfo.packageName);
				}

			} catch (Exception e) {
				// TODO: handle exception
				if (currentShowMode == MODE_SHOW_ALL) {
					mUninstallerAdapter.deleteInfo(currrentApplicationIndex);
					mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
				} else {
					mUninstallerGridAppAdapter
							.deleteInfo(currrentApplicationIndex);
					mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
				}
			}
		}

	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		currentShowMode = MODE_SHOW_ACTIVITY;
		// startService(new Intent(this, AlpAdService.class));
		grid.clearTextFilter();
		grid.setAdapter(null);
		super.onDestroy();
	}

	private void initializeElements() {
		grid = (GridView) findViewById(R.id.gridViewUninstaller);
		txtLoading = (TextView) findViewById(R.id.txtLoading);
		grid.setOnItemClickListener(gridItemClick);

		grid.setTextFilterEnabled(true);
		mPackageManager = getPackageManager();
		mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		mQueuePackages = new LinkedList<PackageInfo>();
		mQueueApps = new LinkedList<ResolveInfo>();
		mConfigManager = ConfigManager.getInstance(this);
		if (mConfigManager.getGridNotiBarEnabled()) {
			showUninstallNotify();
		}
	}

	private void startLoadingPackages() {
		Log.i(TAG, "loading packages...");
		sortMode = MODE_SORT_BY_NAME;
		mPackageInfoList = mPackageManager.getInstalledPackages(0);
		// sortPackagesByDefault(mPackageInfoList);
		int listSize = mPackageInfoList.size();
		int count = listSize / 4;
		// try {
		for (int i = 0; i < count; i++) {
			// Thread.sleep(100);
			synchronized (SYNC) {
				mQueuePackages.offer(mPackageInfoList.get(i * 4));
				mQueuePackages.offer(mPackageInfoList.get(i * 4 + 1));
				mQueuePackages.offer(mPackageInfoList.get(i * 4 + 2));
				mQueuePackages.offer(mPackageInfoList.get(i * 4 + 3));
				mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
				try {
					SYNC.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		}
		if (count * 4 < listSize) {
			for (int j = count * 4; j < listSize; j++) {
				mQueuePackages.offer(mPackageInfoList.get(j));
			}
			mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
		}
	}

	private void startLoadingApps() {
		Log.i(TAG, "loading apps...");
		sortMode = MODE_SORT_BY_NAME;
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_MAIN);
		intent.addCategory(Intent.CATEGORY_LAUNCHER);
		mApplicationInfoList = mPackageManager.queryIntentActivities(intent, 0);
		// sortAppByDefault(mApplicationInfoList);
		int listSize = mApplicationInfoList.size();

		/**
		 * When fetched 4 items then notify UI thread to update its views.
		 * 
		 * @count here means count of circle
		 */
		int count = listSize / 4;
		for (int i = 0; i < count; i++) {
			synchronized (SYNC) {
				mQueueApps.offer(mApplicationInfoList.get(i * 4));
				mQueueApps.offer(mApplicationInfoList.get(i * 4 + 1));
				mQueueApps.offer(mApplicationInfoList.get(i * 4 + 2));
				mQueueApps.offer(mApplicationInfoList.get(i * 4 + 3));
				mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
				try {
					SYNC.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		if (count * 4 < listSize) {
			for (int j = count * 4; j < listSize; j++) {
				mQueueApps.offer(mApplicationInfoList.get(j));
			}
			mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
		}
	}

	private void startUninstall(String packageName, int flag, int position) {
		Uri uri = Uri.fromParts("package", packageName, null);
		Intent uninstallPackageIntent = new Intent(Intent.ACTION_DELETE, uri);
		startActivityForResult(uninstallPackageIntent, REQUEST_UNINSTALL);
	}

	public void showUninstallNotify() {
		Notification notification = new Notification(R.drawable.icon, null,
				System.currentTimeMillis());
		Intent intent = new Intent(this, UninstallerGrid.class);
		// intent.setAction(Intent.ACTION_SEARCH);
		PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
				intent, 0);
		notification.setLatestEventInfo(this, "App Manager",
				"Launch App Manager GridView", contentIntent);
		notification.flags = Notification.FLAG_AUTO_CANCEL;
		mNotificationManager.notify(NOTIFYCATION_ID, notification);
	}

	public void cancelNotify() {
		try {
			mNotificationManager.cancel(NOTIFYCATION_ID);
		} catch (Exception e) {
			Log.i(TAG, "cancel notify fail");
		}

	}

}